package com.learning.thread.juc.tool;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * ClassName: CountDownLatchFirst
 * Description: CountDownLatch 倒计时计时器
 * <p>
 * <p>
 * 1、犹如倒计时的计时器，调用 CountdownLatch 对象的 countDown() 方法，就将计时器减一当计时器到达0时，则所有线程或单个线程开始执行
 * 2、可以实现一个人（多人）等待其他所有人都来通知他，可以实现一个通知多个人的效果。类似裁判一声令下运动员同时开始奔跑。
 * 3、它允许一个或多个线程一直等待，直到其他线程的操作执行完后再执行。CountDownLatch 这个类能够使一个线程等待其他线程完成各自的工作后再执行（同样的功能类似与，主线程提交一组任务，等所有任务完成后，主线程再次执行，期间一直阻塞）
 * Date: 2016/11/26 17:45
 *
 * @author SAM SHO
 * @version V1.0
 */
public class CountDownLatchFirst {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatchFirst count = new CountDownLatchFirst();
        count.test1();
    }


    void test1() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);

        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new MyThread("Main", countDownLatch));
        executor.execute(new MyThread("Sub", countDownLatch));

        // main方法线程等待上面的两个线程完成后才会执行
        countDownLatch.await();

        System.out.println("~~~ 可以执行了 ~~~");

    }


    class MyThread implements Runnable {

        private final String name;
        private final CountDownLatch latch;

        public MyThread(final String name, final CountDownLatch latch) {
            this.name = name;
            this.latch = latch;
        }

        @Override
        public void run() {
            try {
                Thread.sleep((long) (Math.random() * 10000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程 " + name + " 完成工作");

            latch.countDown();
        }
    }
}
